// 准备参数
// 查询用户的名称
let userName = ''
// 页码
let page = 1
// 页面显示条数
let pageSize = 10
// 当前页码对应的用户列表
let userList = []
// 根据用户名查询到所有用户的总数量
let total = 0
// 修改用户的id编号
let updateUserId = 0
// 页面的搜索按钮
const searchBtn = document.querySelector('.search-btn')
// 分页器对应的dom对象
const totalEl = document.querySelector('.total')
const pageNumEl = document.querySelector('.pageNum')
const gotoPageNum = document.querySelector('.goto-pageNum')
const pageSizeEl = document.querySelector('#pageSize')
const firstPage = document.querySelector('.first-page')
const prePage = document.querySelector('.pre-page')
const nextPage = document.querySelector('.next-page')
const lastPage = document.querySelector('.last-page')
const goBtn = document.querySelector('.page-nation>.page-nation-right>.btn')
// 添加用户按钮
const addBtn = document.querySelector('.add-btn')
// 添加对话框中的dom对象
const addDialog = document.querySelector('.add-dialog')
const colseBtn = document.querySelector('.colse-btn')
const cancelAdd = document.querySelector('.cancel-add')
const confirmAdd = document.querySelector('.confirm-add')
const userCode = document.querySelector('#userCode')
const userNameEl = document.querySelector('#userName')
const validList = Array.from(document.querySelectorAll('.valid'))
const addForm = document.querySelector('.add-form')
const userPassword = document.querySelector('#userPassword')
const phone = document.querySelector('#phone')
const birthday = document.querySelector('#birthday')
const address = document.querySelector('#address')
// 用户详情对话框dom对象
const detaildDialog = document.querySelector('.detail-dialog')
const detailCloseBtn = document.querySelector('.detail-dialog .colse-btn')
// 修改对话框中的dom对象
const updateDialog = document.querySelector('.update-dialog')
const updateCloseBtn = document.querySelector('.update-dialog .colse-btn')
const updateUserCode = document.querySelector('.update-dialog #userCode')
const updateUserName = document.querySelector('.update-dialog #userName')
const updategGenders = document.querySelectorAll('.update-dialog .gender')
const updatePhone = document.querySelector('.update-dialog #phone')
const updateUserRole = document.querySelector('.update-dialog #userRole')
const updateBirthday = document.querySelector('.update-dialog #birthday')
const updateAddress = document.querySelector('.update-dialog #address')
const updateId = document.querySelector('.update-dialog #hidden-id')
const updateDialogConfirmBtn = document.querySelector('.update-dialog .confirm-add')
// 退出按钮
const logoutBtn = document.querySelector('.logout')
logoutBtn.onclick = () => {
  // 删除登陆信息
  sessionStorage.removeItem('USER_LOGIN')
  localStorage.removeItem('LOGIN_INFO')
  // 跳转页面
  location = './login.html'
}
// 获得修改表单元素的值
function getUpdateUserParams() {
  let gender = updategGenders[0].checked ? updategGenders[0].value : updategGenders[1].value
  let object = {
    id: updateUserId,
    userName: updateUserName.value,
    gender,
    birthday: updateBirthday.value,
    address: updateAddress.value,
    userRole: updateUserRole.value,
    phone: updatePhone.value,
  }
  // 获得对象的属性名称字符串数组，可以获得对象的Symbol类型的属性
  let keys = Reflect.ownKeys(object) // 反射
  let arr = []
  for (let item of keys) {
    arr.push(`${item}=${object[item]}`)
  }
  let params = arr.join('&')
  return params
}
// 通过id修改用户信息
function updateUserById() {
  return new Promise((resolve, reject) => {
    let xhr = null
    if (XMLHttpRequest) {
      xhr = new XMLHttpRequest()
    } else {
      xhr = new ActiveXObject('Microsoft.XMLHTTP')
    }
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4 && xhr.status === 200) {
        let res = xhr.responseText
        if (res) {
          res = JSON.parse(res)
          if (res.code === 200) {
            resolve(res)
          } else {
            reject(res)
          }
        }
      }
    }
    xhr.open('PUT', 'http://146.56.230.35:3007/users/updateUserById', true)
    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
    xhr.setRequestHeader('token', getToken())
    xhr.send(getUpdateUserParams())
  })
}
// 验证修改表单
function validUpdateForm() {
  let flag =
    validUserName.call(updateUserName) &
    validBirthday.call(updateBirthday) &
    validAddress.call(updateAddress) &
    validPhone.call(updatePhone)
  return flag === 1
}
// 修改对话框中的确认按钮点击执行的回调函数
updateDialogConfirmBtn.onclick = async function () {
  console.log(1111)
  // 验证表单
  let valid = validUpdateForm()
  if (!valid) {
    return alert('请正确填写用户信息')
  }

  try {
    // 发送请求
    let res = await updateUserById()
    // 判断请求是否成功
    if (res.code !== 200) {
      return alert(res.msg)
    }
    alert(res.msg)
    // 关闭对话框
    updateDialog.style.display = 'none'
    // 重新加载数据
    init()
  } catch (error) {
    console.log(error)
  }
}
// 修改对话框表单验证
updateUserCode.onblur = validUserCode
updateUserName.onblur = validUserName
updatePhone.onblur = validPhone
updateBirthday.onblur = validBirthday
updateAddress.onblur = validAddress

// 修改对话框的关闭按钮点击效果
updateCloseBtn.onclick = function () {
  updateDialog.style.display = 'none'
}
// 详情对话框的关闭按钮点击效果
detailCloseBtn.onclick = function () {
  detaildDialog.style.display = 'none'
}
// 执行用户的添加操作
function addUser() {
  // 返回数据
  return new Promise((v, j) => {
    // 准备参数
    let xhr = null
    if (XMLHttpRequest) {
      xhr = new XMLHttpRequest()
    } else {
      xhr = new ActiveXObject('Microsoft.XMLHTTP')
    }
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4 && xhr.status === 200) {
        let res = xhr.responseText
        if (res) {
          res = JSON.parse(res)
          // 使用promise保存数据
          if (res.code === 200) {
            v(res)
          } else {
            j(res)
          }
        }
      }
    }
    // 发送请求
    let url = 'http://146.56.230.35:3007/users/createUser'
    let method = 'POST'
    let asc = true
    xhr.open(method, url, asc)
    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
    xhr.setRequestHeader('token', getToken())
    // 获得性别
    let genders = Array.from(document.getElementsByClassName('gender'))
    let gen = 2
    for (let item of genders) {
      if (item.checked) {
        gen = +item.value
        break
      }
    }
    // 要传递给服务器的所有属性参数
    let params = {
      userCode: userCode.value,
      userName: userNameEl.value,
      userPassword: userPassword.value,
      gender: gen,
      phone: phone.value,
      userRole: +document.querySelector('#userRole').value,
      birthday: birthday.value,
      address: address.value,
    }
    // keys是params对象所有的属性名称的数组['userCode','userName',...,'address']
    let keys = Object.keys(params)
    let arr = []
    for (let prop of keys) {
      // prop是数组keys的元素，是params对象的属性名称
      arr.push(`${prop}=${params[prop]}`) // userCode=toore
    }
    xhr.send(arr.join('&'))
  })
}
// 验证地址
address.onblur = validAddress
function validAddress() {
  // 获得地址元素的值
  let v = this.value
  // 获得地址元素验证信息显示的元素
  let valid = this.parentNode.nextElementSibling
  // 清空验证信息
  valid.innerHTML = ''
  if (!v) {
    valid.innerHTML = '地址不能为空'
    return false
  }
  return true
}
// 验证生日
birthday.onchange = validBirthday
function validBirthday() {
  let v = this.value
  // 验证用户密码的元素
  let valid = this.parentNode.nextElementSibling
  valid.innerHTML = ''
  if (!v) {
    valid.innerHTML = '生日不能为空'
    return false
  }
  return true
}
// 验证电话号码
phone.onblur = validPhone
phone.onfocus = function () {
  // 获得焦点时清空验证规则
  phone.parentNode.nextElementSibling.innerHTML = ''
  // 也清空自己值
  phone.value = ''
}
function validPhone() {
  let v = this.value
  // 验证用户密码的元素
  let valid = this.parentNode.nextElementSibling
  valid.innerHTML = ''
  // 声明正则表达式
  let reg = /^1[3-9]\d{9}$/
  if (!reg.test(v)) {
    valid.innerHTML = '电话号码以1开头，第2位是3456789任意1位，共11位数字'
    return false
  }
  return true
}
// 密码框失去焦点的验证
userPassword.onblur = validUserPassword
function validUserPassword() {
  let v = this.value
  // 验证用户密码的元素
  let valid = this.parentNode.nextElementSibling
  valid.innerHTML = ''
  // 声明正则表达式
  let reg = /^[a-zA-Z\d_$()-+*&{}@!%]{6,12}$/
  if (!reg.test(v)) {
    valid.innerHTML = '密码由英文、数字、下划线、特殊字符组成6-12位'
    return false
  }
  // 判断是否有特殊字符
  let str = `_$()-+*&{}@!%`
  let flag = false
  for (let i = 0; i < v.length; i++) {
    if (str.includes(v[i])) {
      flag = true
      break
    }
  }
  if (!flag) {
    valid.innerHTML = '密码必须包含以下任意一种特殊字符_$()-+*&{}@!%'
    return false
  }
  return true
}
userPassword.onfocus = function () {
  // 获得焦点时清空验证规则
  userPassword.parentNode.nextElementSibling.innerHTML = ''
  // 也清空自己值
  userPassword.value = ''
}
// 用户名称失去焦点时触发的函数
userNameEl.onblur = validUserName
// 验证用户名称的函数
function validUserName() {
  let v = this.value
  // 验证用户编码的元素
  let valid = this.parentNode.nextElementSibling
  valid.innerHTML = ''
  // 声明正则表达式
  let reg = /^[a-zA-Z\d_]{6,12}$/
  if (!reg.test(v)) {
    valid.innerHTML = '用户名称使用英文、数字、下划线组成6-12位'
    return false
  }
  return true
}
userNameEl.onfocus = function () {
  // 获得焦点时清空验证规则
  userNameEl.parentNode.nextElementSibling.innerHTML = ''
  // 也清空自己值
  userNameEl.value = ''
}
// 用户编码失去焦点时触发的函数
userCode.onblur = validUserCode
// 获得焦点，鼠标光标进入时
userCode.onfocus = function () {
  // 获得焦点时清空验证规则
  userCode.parentNode.nextElementSibling.innerHTML = ''
  // 也清空自己值
  userCode.value = ''
}
function validUserCode() {
  let v = this.value
  // 验证用户编码的元素
  let valid = this.parentNode.nextElementSibling
  valid.innerHTML = ''
  // 声明正则表达式
  let reg = /^[a-zA-Z\d_]{6,12}$/
  if (!reg.test(v)) {
    valid.innerHTML = '用户编码使用英文、数字、下划线组成6-12位'
    return false
  }
  return true
}

// 取消添加按钮点击事件回调函数
cancelAdd.onclick = function () {
  // 表单重置
  addForm.reset()
  // 清空所有的valid元素
  validList.forEach((it) => (it.innerHTML = ''))
  // 关闭对话框
  addDialog.style.display = 'none'
}
// 确认添加按钮点击事件回调函数
confirmAdd.onclick = async function () {
  let flag =
    validAddress.call(address) &
    validUserCode.call(userCode) &
    validUserName.call(userNameEl) &
    validUserPassword.call(userPassword) &
    validPhone.call(phone) &
    validBirthday.call(birthday)
  if (!flag) {
    // flag = 0 表示验证失败了
    return alert('请正确填写用户信息')
  }
  // 表单验证正确可以发送ajax请求实现用户的添加
  try {
    let res = await addUser()
    if (res.code !== 200) {
      return alert(res.msg)
    }
    alert('添加成功')
    // 关闭对话框
    addDialog.style.display = 'none'
    // 重置表单
    addForm.reset()
    // 重新加载数据
    init()
  } catch (error) {}
}
// 点击关闭添加对话框
colseBtn.addEventListener(
  'click',
  function () {
    addForm.reset()
    validList.forEach((it) => (it.innerHTML = ''))
    addDialog.style.display = 'none'
  },
  false
)

// 点击添加用户按钮显示添加对话框
addBtn.addEventListener(
  'click',
  function () {
    addDialog.style.display = 'flex'
  },
  false
)

// 页面显示条数的下拉框发生变化的操作
pageSizeEl.onchange = function () {
  let v = +this.value
  page = 1
  pageSize = v
  init()
}
// GO按钮点击时的操作
goBtn.onclick = () => {
  let reg = /^\d+$/
  let v = gotoPageNum.value
  if (!reg.test(v)) {
    gotoPageNum.value = page
    return
  }
  page = +v
  if (page < 1) {
    page = 1
  }
  let totalPage = Math.ceil(total / pageSize)
  if (page > totalPage) {
    page = totalPage
  }
  init()
}

// 在去第n页的input上回车操作
gotoPageNum.onkeyup = function (e) {
  let reg = /^\d+$/
  if (e.keyCode === 13) {
    let v = gotoPageNum.value
    if (!reg.test(v)) {
      gotoPageNum.value = page
      return
    }
    page = +v
    if (page < 1) {
      page = 1
    }
    let totalPage = Math.ceil(total / pageSize)
    if (page > totalPage) {
      page = totalPage
    }
    init()
  }
}
// 点击上一页的操作
prePage.onclick = () => {
  page--
  if (page === 0) {
    page = 1
  }
  init()
}

// 点击下一页的操作
nextPage.onclick = () => {
  page++
  let totalPage = Math.ceil(total / pageSize)
  if (page > totalPage) {
    page = totalPage
  }
  init()
}

// 点击首页的操作
lastPage.onclick = () => {
  page = Math.ceil(total / pageSize)
  init()
}

// 点击首页的操作
firstPage.onclick = () => {
  page = 1
  init()
}

searchBtn.onclick = () => {
  // 获得input框的值进行搜索
  userName = document.querySelector('.search-input').value
  page = 1
  init()
}

// 获得分页的用户列表数据
function getUserList() {
  return new Promise((resolve, reject) => {
    // 1 创建对象
    let xhr = null
    if (XMLHttpRequest) {
      xhr = new XMLHttpRequest()
    } else {
      xhr = new ActiveXObject('Microsoft.XMLHTTP')
    }
    // 2 监听准备状态变化
    xhr.onreadystatechange = function () {
      // 6 当请求数据已经处理结束并且网络状态一切正常
      if (xhr.readyState === 4 && xhr.status === 200) {
        // 7 获得请求的数据
        let data = xhr.responseText
        // 8 data 是一个json字符串，转换为json对象
        let res = JSON.parse(data)
        if (res.code === 200) {
          resolve(res)
        } else {
          reject(res)
        }
      }
    }
    // 3 设置请求方法，接口地址，是否异步
    let url = `http://146.56.230.35:3007/users/userList?userName=${userName}&page=${page}&pageSize=${pageSize}`
    xhr.open('GET', url, true)
    // 4 设置请求头
    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
    // 在请求头中携带token给服务器，否则服务器认为是非法请求，不处理任何数据
    xhr.setRequestHeader('token', getToken()) // getToken在utils.js中
    // 5 发送请求
    xhr.send()
  })
}

// 渲染函数
function render(userList, total) {
  let tr = `<tr class="tr-first">
    <th>序号</th>
    <th>用户编码</th>
    <th>用户名</th>
    <th>性别</th>
    <th>年龄</th>
    <th>电话</th>
    <th>用户类型</th>
    <th>操作</th>
  </tr>`
  for (let i = 0; i < userList.length; i++) {
    // 序号变量
    let index = (page - 1) * pageSize + i + 1
    let item = userList[i]
    let className = 'active'
    if (i % 2 === 0) {
      className = ''
    }
    tr += `<tr class="${className}">
      <td>${index}</td>
      <td>${item.userCode}</td>
      <td>${item.userName}</td>
      <td>${item.gender}</td>
      <td>${getAgeByBirthDay(item.birthday)}</td>
      <td>${item.phone}</td>
      <td>${item.roleName}</td>
      <td>
        <img src='./img/read.png' title="查看" data-id="${item.id}" class="chk-img" />
        <img src='./img/xiugai.png' title="修改" data-id="${item.id}" class="upd-img" />
        <img src='./img/schu.png' title="删除" data-id="${item.id}" role="${item.userRole}" class="del-img" />
      </td>
    </tr>`
  }
  document.querySelector('.users-table').innerHTML = tr
  // 表格拼接结束后开始对元素绑定事件
  let delImgList = Array.from(document.querySelectorAll('.del-img'))
  // 遍历数组元素
  delImgList.forEach((item) => {
    // 给每个删除图片绑定点击事件
    item.onclick = async function (e) {
      // 删除时可能是个误操作，给个确认框，给用户一个反悔的机会
      let rt = confirm('你确定要删除当前对象吗?')
      if (!rt) {
        return alert('你取消了删除!!!')
      }
      // e.target是item对象本身，是delImgList数组的元素，是img.del-img元素，元素上有个属性data-id
      let userId = +e.target.getAttribute('data-id')
      // 如果删除的用户id和登录的用户id相等，不能删除此用户
      if (userId === getLoginIdFromSessionStorage()) {
        return alert('当前登录用户不能删除')
      }
      // 超级管理员不能删除
      let userRole = +e.target.getAttribute('role')
      if (userRole === 1) {
        return alert('超级管理员不能删除')
      }
      try {
        // 执行删除操作
        let res = await removeUserById(userId)
        // 判断删除失败
        if (res.code !== 200) {
          return alert(res.msg)
        }
        // 判断删除成功
        alert('删除成功')
        // 不是第1页，且这一页数据只有1条，删除后，页面的页码向前翻一页: page--
        if (page !== 1 && userList.length === 1) {
          page--
        }
        // 重新加载数据
        init()
      } catch (error) {}
    }
  })
  // 查看用户信息
  let chk_img_list = Array.from(document.querySelectorAll('.chk-img'))
  chk_img_list.forEach((item) => {
    item.onclick = async function (e) {
      try {
        // 点击获得当前对象的id
        let id = +e.target.getAttribute('data-id')
        // 根据id请求用户对象
        let res = await getUserById(id)
        // 显示用户详情的对话框方法
        showUserDetailDialog(res)
      } catch (error) {}
    }
  })
  // 修改用户信息
  let upd_img_list = Array.from(document.querySelectorAll('.upd-img'))
  upd_img_list.forEach((item) => {
    item.onclick = async function (e) {
      try {
        // 点击获得当前对象的id
        let id = +e.target.getAttribute('data-id')
        // 根据id请求用户对象
        let res = await getUserById(id)
        // 显示用户详情的对话框方法
        showUpdateDialog(res)
      } catch (error) {}
    }
  })
}

// 显示修改对话框
function showUpdateDialog(res) {
  // 获得根据id请求到的对象user
  let { user } = res
  // user绑定数据到修改对话框
  updateUserId = user.id
  updateId.value = user.id
  updateUserCode.value = user.userCode
  updateUserName.value = user.userName
  updatePhone.value = user.phone
  updateBirthday.value = user.birthday
  updateUserRole.value = user.userRole
  updateAddress.value = user.address
  updategGenders.forEach((item) => {
    let gender = user.gender === '男' ? '1' : '2'
    item.checked = false
    if (item.value === gender) {
      item.checked = true
    }
  })
  // 显示对话框
  updateDialog.style.display = 'flex'
}

// 显示用户详情前绑定数据到对话框中
function showUserDetailDialog(res) {
  let dialog = document.querySelector('.detail-dialog')
  dialog.style.display = 'flex'
  // 获得对象的所有属性名称数组
  let keys = Object.keys(res.user)
  let str = ''
  for (let key of keys) {
    str += `<div class="item">
      <div class="key">${key}:</div>
      <div class="value">${res.user[key]}</div>
    </div>`
  }
  document.querySelector('.detail-dialog>.content>.bodys').innerHTML = str
}

// 根据id请求用户对象
async function getUserById(id) {
  return new Promise((resovle, reject) => {
    let xhr = null
    if (XMLHttpRequest) {
      xhr = new XMLHttpRequest()
    } else {
      xhr = new ActiveXObject('Microsoft.XMLHTTP')
    }
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4 && xhr.status === 200) {
        let res = xhr.responseText
        if (res) {
          res = JSON.parse(res)
          if (res.code === 200) {
            resovle(res)
          } else {
            reject(res)
          }
        }
      }
    }
    xhr.open('GET', 'http://146.56.230.35:3007/users/getUserById?id=' + id, true)
    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
    xhr.setRequestHeader('token', getToken())
    xhr.send()
  })
}

// 根据id删除数据库中的用户
function removeUserById(userId) {
  // 返回请求数据
  return new Promise((resovle, reject) => {
    // 创建ajax
    let xhr = null
    if (XMLHttpRequest) {
      xhr = new XMLHttpRequest()
    } else {
      xhr = new ActiveXObject('Microsoft.XMLHTTP')
    }
    xhr.onreadystatechange = function () {
      // 获得相应数据
      if (xhr.readyState === 4 && xhr.status === 200) {
        let res = xhr.responseText
        if (res) {
          res = JSON.parse(res)
          if (res.code === 200) {
            resovle(res)
          } else {
            reject(res)
          }
        }
      }
    }
    // 发送请求
    xhr.open('DELETE', 'http://146.56.230.35:3007/users/deleteUserById?id=' + userId, true)
    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
    xhr.setRequestHeader('token', getToken())
    xhr.send()
  })
}

// 初始化页面数据
async function init() {
  try {
    let res = await getUserList()
    // 判断请求列表的结果，code !==200 表示请求失败
    if (res.code !== 200) {
      return alert(res.msg)
    }
    // 请求成功，取出用户列表，取出总条数
    userList = res.data.list
    total = res.data.count
    console.log(userList)
    console.log(total)
    // 调用渲染函数
    render(userList, total)
    // 计算总页数
    let totalPage = Math.ceil(total / pageSize)
    totalEl.innerHTML = totalPage
    // 设置第n页
    pageNumEl.innerHTML = page
    gotoPageNum.value = page
    // 设置页面显示条数的下拉框值
    pageSizeEl.value = pageSize
  } catch (error) {
    console.log(error)
  }
  console.log('init结束')
}

// 设置登录名称
function setLoginName() {
  document.querySelector('.login-name').innerHTML = getLoginNameFromSessionStorage()
}

window.onload = function () {
  init()
  setLoginName()
}
